#region license
# This file is part of Grawlix.
# 
# Grawlix is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
# 
# Grawlix is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public
# License along with Grawlix.  If not, see
# <http://www.gnu.org/licenses/>.
#endregion

"""Control over server side of the network."""

namespace Grawlix.Server
import Grawlix.Meta
import Grawlix.Services
import System
import System.Diagnostics
import System.Threading
import Lidgren.Library.Network

[Disposable(SharedCleanup: Shutdown)]
transient class NetworkServer:
"""Clientside controller."""
	
	def constructor(port as int):
	"""Start up services for the client."""
		_port = port
#		_log = NetLog()
#		_log.Info("Starting server on ${_port}")
#		_log.IgnoreTypes = NetLogEntryTypes.None
#		_log.IsOutputToFileEnabled = true
#		_log.OutputFileName = "Server.html"
	
	def Run():
	"""Main loop for doing network updates."""
		netLog = NetLog()
		netLog.IgnoreTypes = NetLogEntryTypes.None
		netLog.IsOutputToFileEnabled = false
		netLog.LogEvent += WriteLog
		nac = NetAppConfiguration("Grawlix", _port)
		nac.MaximumConnections = 32
		nac.ServerName = "Grawlix"
		_server = NetServer(nac, netLog)
		handler = EventHandler[of NetStatusEventArgs](StatusChanged)
		_server.StatusChanged += handler
		timer = Stopwatch()
		while Thread.VolatileRead(_alive) == Status.Alive:
			elapsed = timer.Elapsed
			timer.Reset()
			timer.Start()
			Update(elapsed)
			left = timer.ElapsedMilliseconds
			Thread.Sleep(Math.Max(100 - left, 10))
		_server.Shutdown("Server shutdown.")
	
	private def WriteLog(sender as object, args as NetLogEventArgs):
	"""
	Write an entry to a log.
	Param sender: The log to write to.
	Param args: The log information.
	"""
		if args.Entry.Type & NetLogEntryTypes.Error:
			log Error, "${args.Entry.Where}: ${args.Entry.What}"
		elif args.Entry.Type & NetLogEntryTypes.Warning:
			log Warn, "${args.Entry.Where}: ${args.Entry.What}"
		elif args.Entry.Type & NetLogEntryTypes.Debug:
			log Debug, "${args.Entry.Where}: ${args.Entry.What}"
		else:
			log Info, "${args.Entry.Where}: ${args.Entry.What}"
	
	def Exit():
	"""Stop the main loop."""
		Thread.VolatileWrite(_alive, cast(int, Status.Dead))
	
	private def Shutdown():
	"""Get rid of the connection."""
		_server.Shutdown("Disposing of the server.")
		_server = null
	
	private def StatusChanged(sender as object, args as NetStatusEventArgs):
	"""
	Change the status of the 
	Param sender: The object that sent this event.
	Param args: The event arguments.
	"""
#		if args.Connection.Status == NetConnectionStatus.Connecting:
#			_log.Info("Someone is connecting")
#		elif args.Connection.Status == NetConnectionStatus.Connected:
#			_log.Info("Someone has connected.")
#		elif args.Connection.Status == NetConnectionStatus.Disconnected:
#			_log.Info("Disconnected from the server")
		pass
	
	def Update(elapsed as timespan):
	"""
	Receive networking events.
	Param elapsed: Time elapsed since last update.
	"""
		_server.Heartbeat()
		while ((msg = _server.ReadMessage()) != null):
			truemsg as string = msg.ReadString()
			log Info, ("Got a message. Content: \"${truemsg}\"")
	
	def Output():
	"""Send out world network packets."""
		pass
	
	[property(Game)]
	[IgnoreDisposal]
	private _game as Game
	"""The model of the game world."""
	
	private _server as NetServer
	"""The internal handler."""
	
	[getter(Port)]
	private _port as int
	"""The port to connect to."""
	
	private _alive = cast(int, Status.Alive)
	"""Dead means loop needs to stop."""
	
	private enum Status:
	"""Whether the client is alive or dead."""
		Alive
		"""The client is running."""
		Dead
		"""The client is not running."""




